package websocket

import (
	"fmt"
	"time"

	"github.com/gorilla/websocket"
	"github.com/sirupsen/logrus"
)

// Hub maintains the set of active clients and broadcasts messages to the
// clients.
type Hub struct {
	// Registered clients.
	clients map[*Client]bool

	// Inbound messages from the clients.
	// broadcast chan []byte
	broadcast chan *WsMessage

	// Register requests from the clients.
	register chan *Client

	// Unregister requests from clients.
	unregister chan *Client

	userClients map[string]*Client
}

func NewHub() *Hub {
	return &Hub{
		// broadcast:   make(chan []byte),
		broadcast:   make(chan *WsMessage),
		register:    make(chan *Client),
		unregister:  make(chan *Client),
		clients:     make(map[*Client]bool),
		userClients: make(map[string]*Client),
	}
}

func (h *Hub) Run() {
	for {
		select {
		case client := <-h.register:
			// h.clients[client] = true
			h.userClients[client.userId] = client
		case client := <-h.unregister:
			// if _, ok := h.clients[client]; ok {
			// 	delete(h.clients, client)
			// 	close(client.send)
			// }
			if _, ok := h.userClients[client.userId]; ok {
				delete(h.userClients, client.userId)
				close(client.send)
			}
		case message := <-h.broadcast:
			// for client := range h.clients {
			// 	select {
			// 	case client.send <- message:
			// 	default:
			// 		close(client.send)
			// 		delete(h.clients, client)
			// 	}
			// }

			if len(message.UserId) > 0 {
				if client, ok := h.userClients[message.UserId]; ok {
					select {
					case client.send <- message.Content:
						//Todo: 记录发送内容
					default:
						close(client.send)
						delete(h.userClients, client.userId)
					}
				}
			} else {
				for _, client := range h.userClients {
					select {
					case client.send <- message.Content:
						//Todo: 记录发送内容
					default:
						close(client.send)
						delete(h.userClients, client.userId)
					}
				}
			}
		}
	}
}

func (h *Hub) SendMessage(message []byte, userId string) error {
	// logrus.Info(fmt.Sprintf("Hub.SendMessage : %+v, %+v", userId, message))
	if len(userId) > 0 {
		// logrus.Info(fmt.Sprintf("Hub.SendMessage userClients : %+v ", h.userClients))
		if client, ok := h.userClients[userId]; ok {
			// logrus.Info(fmt.Sprintf("Hub.SendMessage client1 : %+v ", client.userId))
			client.conn.SetWriteDeadline(time.Now().Add(writeWait))
			if err := client.conn.WriteMessage(websocket.TextMessage, message); err != nil {
				return err
			}
		} else {
			logrus.Info(fmt.Sprintf("Hub.SendMessage client2 : %+v ", client.userId))
		}
	} else {
		for _, client := range h.userClients {
			client.conn.SetWriteDeadline(time.Now().Add(writeWait))
			if err := client.conn.WriteMessage(websocket.TextMessage, message); err != nil {
				return err
			}
		}
	}

	return nil
}
